<?php
/**
 * Created by PhpStorm.
 * User: fangwei
 * Date: 2019-08-21
 * Time: 16:59
 */

namespace App\Http\Repositories\Services\Impls;


use App\Exceptions\ServiceException;
use App\Http\Constants\CommonExceptionConstants;
use App\Http\Repositories\Daos\IBrandDao;
use App\Http\Repositories\Daos\IProductDao;
use App\Http\Repositories\Daos\IProductItemDao;
use App\Http\Repositories\Eloquent\Brand;
use App\Http\Repositories\Eloquent\Product;
use App\Http\Repositories\Eloquent\ProductItem;
use App\Http\Repositories\Eloquent\ProductSite;
use App\Http\Repositories\Services\IProduct;
use App\Http\Requests\Admin\ProductInputDTO;
use App\Util\Helper;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\DB;

class ProductService implements IProduct
{
    protected $productDao;
    protected $productItemDao;
    protected $brandDao;

    public function __construct(
        IProductDao $productDao,
        IProductItemDao $productItemDao,
        IBrandDao $brandDao
    )
    {
        $this->productDao = $productDao;
        $this->productItemDao = $productItemDao;
        $this->brandDao = $brandDao;
    }

    public function byId($id)
    {
        $dao = $this->productDao->find($id);
        if (!$dao) {
            throw new ServiceException(CommonExceptionConstants::getKey('no_find_data'));
        }
        $item = $this->productItemDao->byProductId($dao->id);
        $itemIds = [];
        $itemData = [];
        if ($item->count()) {
            foreach ($item as $key => $val) {
                $itemIds[] = $val->product_site_id;
                $itemData[$val->product_site_id] = $val->amount;
            }
        }
        $dao->itemIds = $itemIds;
        $dao->itemData = $itemData;
        return $dao;
    }

    public function store(ProductInputDTO $inputDTO)
    {
        $dao = new Product();
        $dao->name = $inputDTO->get('name');
        $dao->brand_id = $inputDTO->get('brand_id');
        $dao->brand_model_id = $inputDTO->get('brand_model_id');
        $dao->year = $inputDTO->get('year');
        $dao->product_model = $inputDTO->get('product_model');
        $dao->cover = $inputDTO->get('cover');
        $dao->note = $inputDTO->get('note');
        $dao->save();

        $item = $inputDTO->get('item');
        $this->_saveItem($item, $dao->id);
    }

    public function update(ProductInputDTO $inputDTO, $id)
    {
        $dao = $this->productDao->find($id);
        if (!$dao) {
            throw new ServiceException(CommonExceptionConstants::getKey('no_find_data'));
        }
        $dao->name = $inputDTO->get('name');
        $dao->brand_id = $inputDTO->get('brand_id');
        $dao->brand_model_id = $inputDTO->get('brand_model_id');
        $dao->year = $inputDTO->get('year');
        $dao->product_model = $inputDTO->get('product_model');
        $dao->cover = $inputDTO->get('cover');
        $dao->note = $inputDTO->get('note');
        $dao->save();

        $item = $inputDTO->get('item');
        $this->_saveItem($item, $dao->id);
    }

    public function delete($ids)
    {
        if (is_array($ids)) {
            $where = [];
            $where['id'] = [
                'symbol' => 'in',
                'val' => $ids
            ];
            $this->productDao->update($where,['is_deleted'=>1]);
        }else{
            $dao = $this->productDao->find(intval($ids));
            if (!$dao) {
                throw new ServiceException(CommonExceptionConstants::getKey('no_find_data'));
            }
            $dao->is_deleted = 1;
            $dao->save();
        }

    }

    private function _saveItem($item, $id) {
        if (!is_array($item)) {
            return false;
        }
        foreach ($item as $key => $val) {
            $dao = $this->productItemDao->byProductId($id, $val['id']);
            if (!$dao) {
                $dao = new ProductItem();
            } else {
                if (!$val['amount']) {
                    $dao->delete();
                }
            }
            if (!$val['amount']) {
                continue;
            }
            $dao->product_id = $id;
            $dao->product_site_id = $val['id'];
            $dao->amount = $val['amount'];
            $dao->save();
        }
    }

    public function lists($search, $page, $size)
    {
        $data =  $this->productDao->lists($search, $page, $size);
        if ($data['results']) {
            foreach ($data['results'] as $key => &$val) {
                $val['brand_name'] = Brand::map($val['brand_id'],'name');
                $val['brand_model_name'] = Brand::map($val['brand_model_id'],'name');
                $val['year_name'] = Config::get('constant.year.'.$val['year']);
                $val['product_model_name'] = Config::get('constant.product_model.'.$val['product_model']);
            }
        }
        return $data;
    }

    public function state($id, $val)
    {
        $dao = $this->productDao->find($id);
        if (!$dao) {
            throw new ServiceException(CommonExceptionConstants::getKey('no_find_data'));
        }
        $dao->state = $val;
        $dao->update();
    }

    public function byProduct($search)
    {
        $data = [];
        $dao = $this->productDao->byProduct($search);
        if (!$dao) {
            return $data;
        }
        $siteDao = ProductSite::all();
        $daoItem = $this->productItemDao->byProductId($dao->id);
        if ($daoItem) {
            $daoItem = Helper::arrayMapByKey($daoItem->toArray(),'product_site_id');
        }

        $brand = $this->brandDao->find($dao->brand_id);
        $brandModel = $this->brandDao->find($dao->brand_model_id);
        $data['cover'] = $dao->cover ?? '';
        $data['brand_name'] = $brand->name ?? '';
        $data['brand_model_name'] = $brandModel->name ?? '';
        $data['year_name'] = Config::get('constant.year.'.$dao->year);
        $data['product_model_name'] = Config::get('constant.product_model.'.$dao->product_model);
        $site = [];
        $i = 0;

        foreach ($siteDao as $key => $val) {
            if ($val->is_deleted) {
                continue;
            }
            if (!isset($daoItem[$val->id])) {
                continue;
            }
            $site[$i]['id'] = $val->id;
            $site[$i]['name'] = $val->name;
            $site[$i]['cover'] = $val->cover;
            $site[$i]['isChecked'] = true;
            $site[$i]['amount'] = 0;
            $site[$i]['amount'] = $daoItem[$val->id]['amount'];
            $i++;
        }
        $data['site'] = $site;
        return $data;
    }

    public function pl()
    {
        $productModel = Config::get('constant.product_model');

//        $site = DB::table('product_sites')
//            ->where('is_deleted',0)
//            ->where('amount','>',0)
//            ->get();

        $brand = DB::table('brands')
            ->where('is_deleted',0)
            ->where('parent_id',0)
            ->get();
        if (!$brand->count()) {
            return ;
        }
        foreach ($brand as $key => $val) {
            $parent = DB::table('brands')
                ->where('is_deleted',0)
                ->where('parent_id',$val->id)
                ->get();
            if ($parent->count()) {
                foreach ($parent as $k => $v) {
                    foreach ($productModel as $a => $b) {
                        $dao = DB::table('products')
                            ->where('brand_id', $val->id)
                            ->where('brand_model_id', $v->id)
                            ->where('product_model', $a)
                            ->first();
                        $data = [];
                        $data['name'] = $val->name.$v->name.'-'.$b;
                        $data['brand_id'] = $val->id;
                        $data['brand_model_id'] = $v->id;
                        $data['product_model'] = $a;
                        $data['year'] = 1;
                        $data['updated_at'] = time();
                        if ($dao) {
                            $id = $dao->id;
                        } else {
                            $data['created_at'] = time();
                            $data['cover'] = '';
                            $data['note'] = '';
                            $id = DB::table('products')->insertGetId($data);
                        }
                        $site = Config::get('constant.site.'.$a);
                        $this->_siteInsert($id, $site);
                    }
                }
            }
        }

    }

    private function _siteInsert($id, $site)
    {
        if (!$site) {
            return ;
        }
        foreach ($site as $key => $val) {
            $dao = DB::table('product_items')
                ->where('product_id',$id)
                ->where('product_site_id', $key)
                ->first();
            $data = [];
            $data['product_id'] = $id;
            $data['product_site_id'] = $key;
            $data['amount'] = $val;
            $data['updated_at'] = time();
            if ($dao) {
                DB::table('product_items')
                    ->where('id', $dao->id)
                    ->update($data);
            } else {
                $data['created_at'] = time();
                DB::table('product_items')->insert($data);
            }

        }
    }

}